﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;

namespace System
{
    public static class ObjectExtensions
    {
        /// <summary>
        /// 深拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">The source.</param>
        /// <returns>T.</returns>
        public static T CloneJson<T>(this T source) where T : class, new()
        {
            if (source == null)
            {
                return null;
            }
            var s = JsonConvert.SerializeObject(source);
            return (T)JsonConvert.DeserializeObject(s, source.GetType());
        }

        /// <summary>
        /// WPF查找指定类型子元素
        /// </summary>
        /// <typeparam name="T">The type of the child item.</typeparam>
        /// <param name="obj">The object.</param>
        /// <returns>childItem.</returns>
        public static T GetChildObject<T>(this DependencyObject obj) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is T)
                    return (T)child;
                else
                {
                    T childOfChild = GetChildObject<T>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }

        /// <summary>
        /// WPF查找指定类型子元素
        /// </summary>
        /// <typeparam name="T">The type of the child item.</typeparam>
        /// <param name="obj">The object.</param>
        /// <returns>childItem.</returns>
        public static List<T> GetChildObjects<T>(this DependencyObject obj) where T : DependencyObject
        {
            List<T> infos = new List<T>(); ;
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is T)
                {
                    infos.Add((T)child);
                }
                else
                {
                    List<T> childOfChild = GetChildObjects<T>(child);
                    if (childOfChild != null)
                    {
                        infos.AddRange(childOfChild);
                    }
                }
            }
            return infos;
        }

        /// <summary>
        /// 查找父控件
        /// </summary>
        /// <typeparam name="T">父控件的类型</typeparam>
        /// <param name="obj">要找的是obj的父控件</param>
        /// <param name="name">想找的父控件的Name属性</param>
        /// <returns>目标父控件</returns>
        public static T GetParentObject<T>(this DependencyObject obj, string name = "") where T : FrameworkElement
        {
            DependencyObject parent = VisualTreeHelper.GetParent(obj);

            while (parent != null)
            {
                if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)parent;
                }

                // 在上一级父控件中没有找到指定名字的控件，就再往上一级找
                parent = VisualTreeHelper.GetParent(parent);
            }

            return null;
        }

        /// <summary>
        /// 判断滚动条是否到达最底部的代码.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <returns><c>true</c> if [is vertical scroll bar at buttom] [the specified s]; otherwise, <c>false</c>.</returns>
        public static bool IsVerticalScrollBarAtButtom(this ScrollViewer s)
        {
            double dVer = s.VerticalOffset;
            double dViewport = s.ViewportHeight;
            double dExtent = s.ExtentHeight;
            bool isAtButtom = dVer != 0 && dVer + dViewport == dExtent;
            if (s.VerticalScrollBarVisibility == ScrollBarVisibility.Disabled ||
                s.VerticalScrollBarVisibility == ScrollBarVisibility.Hidden)
            {
                isAtButtom = false;
            }
            return isAtButtom;
        }

        /// <summary>
        /// 判断滚动条是否到达最右侧的代码.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <returns><c>true</c> if [is vertical scroll bar at buttom] [the specified s]; otherwise, <c>false</c>.</returns>
        public static bool IsHorizontalScrollBarAtButtom(this ScrollViewer s)
        {
            double dVer = s.HorizontalOffset;
            double dViewport = s.ViewportWidth;
            double dExtent = s.ExtentWidth;
            bool isAtButtom = dVer != 0 && dVer + dViewport == dExtent;
            if (s.HorizontalScrollBarVisibility == ScrollBarVisibility.Disabled ||
                s.HorizontalScrollBarVisibility == ScrollBarVisibility.Hidden)
            {
                isAtButtom = false;
            }
            return isAtButtom;
        }
    }
}
